package com.java.example.util.file

import android.content.Context
import android.os.Environment
import android.util.Log
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Request.Builder
import okhttp3.Response
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream

class DownloadUtil private constructor() {
    private val okHttpClient = OkHttpClient()
    private var context: Context? = null
    private val TAG = "下载页面"

    /**
     * @param url 下载连接
     * @param saveDir 储存下载文件的SDCard目录
     * @param listener 下载监听
     */
    fun download(context: Context?, url: String?, saveDir: String, fileName: String?, listener: OnDownloadListener) {
        this.context = context

        // 需要token的时候可以这样做
        // SharedPreferences sp=MyApp.getAppContext().getSharedPreferences("loginInfo", MODE_PRIVATE);
        // Request request = new Request.Builder().header("token",sp.getString("token" , "")).url(url).build();
        val request: Request = Builder().url(url!!).build()

        okHttpClient.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                // 下载失败
                listener.onDownloadFailed()
            }

            @Throws(IOException::class)
            override fun onResponse(call: Call, response: Response) {
                var `is`: InputStream? = null
                val buf = ByteArray(2048)
                var len = 0
                var fos: FileOutputStream? = null
                // 储存下载文件的目录
                val savePath = isExistDir(saveDir)
                Log.d(TAG, "存储下载目录：$savePath")
                try {
                    `is` = response.body!!.byteStream()
                    val total = response.body!!.contentLength()
                    val file = File(savePath, fileName)
                    Log.w(TAG, "最终路径：$file")
                    fos = FileOutputStream(file)
                    var sum: Long = 0
                    while ((`is`.read(buf).also { len = it }) != -1) {
                        fos.write(buf, 0, len)
                        sum += len.toLong()
                        val progress = (sum * 1.0f / total * 100).toInt()
                        // 下载中
                        listener.onDownloading(progress)
                    }
                    fos.flush()
                    // 下载完成
                    listener.onDownloadSuccess()
                } catch (e: Exception) {
                    listener.onDownloadFailed()
                } finally {
                    try {
                        `is`?.close()
                    } catch (e: IOException) {
                    }
                    try {
                        fos?.close()
                    } catch (e: IOException) {
                    }
                }
            }
        })
    }

    /**
     * @param saveDir
     * @return
     * @throws IOException
     * 判断下载目录是否存在
     */
    @Throws(IOException::class)
    private fun isExistDir(saveDir: String): String {
        // 下载位置
        val downloadFile = File(Environment.getExternalStorageDirectory().path + "/download/", saveDir)
        if (!downloadFile.mkdirs()) {
            downloadFile.createNewFile()
        }
        val savePath = downloadFile.absolutePath
        Log.w(TAG, "下载目录：$savePath")
        return savePath
    }

    /**
     * @param url
     * @return
     * 传入文件名
     */
    fun getNameFromUrl(url: String): String {
        return url
    }

    interface OnDownloadListener {
        /**
         * 下载成功
         */
        fun onDownloadSuccess()

        /**
         * @param progress
         * 下载进度
         */
        fun onDownloading(progress: Int)

        /**
         * 下载失败
         */
        fun onDownloadFailed()
    }

    companion object {
        private var downloadUtil: DownloadUtil? = null
        fun get(): DownloadUtil? {
            if (downloadUtil == null) {
                downloadUtil = DownloadUtil()
            }
            return downloadUtil
        }
    }
}
